"""云端模板同步API端点。"""

from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
from pydantic import BaseModel, Field
import httpx
import uuid
import logging
import hashlib
import json
from motor.motor_asyncio import AsyncIOMotorDatabase

from ..core.auth import get_current_user
from ..core.database import get_db
from ..core.config import settings

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/models/templates/sync", tags=["template-sync"])

# 云端模板库地址（示例）
TEMPLATE_REGISTRY_URL = getattr(settings, "TEMPLATE_REGISTRY_URL", "https://api.ai-platform.com/templates")


class TemplateSyncRequest(BaseModel):
    """模板同步请求。"""
    
    sync_mode: str = Field(default="merge", pattern="^(merge|replace|update)$")
    providers: Optional[List[str]] = Field(None, description="只同步指定提供商的模板")
    categories: Optional[List[str]] = Field(None, description="只同步指定类别的模板")
    force: bool = Field(default=False, description="强制同步，忽略版本检查")


class TemplateSyncResponse(BaseModel):
    """模板同步响应。"""
    
    success: bool
    synced_count: int
    added: List[str]
    updated: List[str]
    skipped: List[str]
    conflicts: List[Dict[str, Any]]
    timestamp: datetime
    next_sync: Optional[datetime]
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }


class TemplateSyncStatus(BaseModel):
    """同步状态。"""
    
    last_sync: Optional[datetime]
    next_sync: Optional[datetime]
    auto_sync_enabled: bool
    sync_interval_hours: int
    last_error: Optional[str]
    total_templates: int
    local_templates: int
    cloud_templates: int
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }


class CloudTemplate(BaseModel):
    """云端模板数据结构。"""
    
    id: str
    name: str
    provider: str
    category: str
    model_name: str
    base_url: str
    version: str
    checksum: str
    created_at: datetime
    updated_at: datetime
    metadata: Dict[str, Any]


async def fetch_cloud_templates(
    providers: Optional[List[str]] = None,
    categories: Optional[List[str]] = None
) -> List[CloudTemplate]:
    """从云端获取模板列表。"""
    try:
        params = {}
        if providers:
            params["providers"] = ",".join(providers)
        if categories:
            params["categories"] = ",".join(categories)
        
        # 模拟从云端获取模板
        # 实际部署时，这里应该调用真实的云端API
        cloud_templates = [
            {
                "id": "cloud-gpt4-turbo",
                "name": "GPT-4 Turbo (Latest)",
                "provider": "openai",
                "category": "chat",
                "model_name": "gpt-4-turbo-preview",
                "base_url": "https://api.openai.com/v1",
                "version": "2024.01",
                "checksum": hashlib.md5("gpt4-turbo".encode()).hexdigest(),
                "created_at": datetime.utcnow() - timedelta(days=30),
                "updated_at": datetime.utcnow() - timedelta(days=1),
                "metadata": {
                    "description": "最新的GPT-4 Turbo模型",
                    "capabilities": {
                        "max_tokens": 128000,
                        "supports_vision": True,
                        "supports_function_calling": True
                    }
                }
            },
            {
                "id": "cloud-gemini-pro",
                "name": "Gemini Pro",
                "provider": "google",
                "category": "chat",
                "model_name": "gemini-pro",
                "base_url": "https://generativelanguage.googleapis.com/v1",
                "version": "1.0",
                "checksum": hashlib.md5("gemini-pro".encode()).hexdigest(),
                "created_at": datetime.utcnow() - timedelta(days=20),
                "updated_at": datetime.utcnow() - timedelta(days=2),
                "metadata": {
                    "description": "Google的Gemini Pro模型",
                    "capabilities": {
                        "max_tokens": 32768,
                        "supports_vision": True
                    }
                }
            },
            {
                "id": "cloud-mistral-large",
                "name": "Mistral Large",
                "provider": "mistral",
                "category": "chat",
                "model_name": "mistral-large-latest",
                "base_url": "https://api.mistral.ai/v1",
                "version": "2024.01",
                "checksum": hashlib.md5("mistral-large".encode()).hexdigest(),
                "created_at": datetime.utcnow() - timedelta(days=15),
                "updated_at": datetime.utcnow() - timedelta(days=3),
                "metadata": {
                    "description": "Mistral AI的最大模型",
                    "capabilities": {
                        "max_tokens": 32768,
                        "supports_function_calling": True
                    }
                }
            }
        ]
        
        # 过滤
        if providers:
            cloud_templates = [t for t in cloud_templates if t["provider"] in providers]
        if categories:
            cloud_templates = [t for t in cloud_templates if t["category"] in categories]
        
        return [CloudTemplate(**t) for t in cloud_templates]
        
    except Exception as e:
        logger.error(f"获取云端模板失败: {e}")
        raise


def calculate_checksum(template_data: Dict[str, Any]) -> str:
    """计算模板校验和。"""
    # 只对关键字段计算校验和
    key_fields = ["name", "provider", "model_name", "base_url", "version"]
    data_str = json.dumps({k: template_data.get(k) for k in key_fields}, sort_keys=True)
    return hashlib.md5(data_str.encode()).hexdigest()


async def resolve_conflict(
    local_template: Dict[str, Any],
    cloud_template: CloudTemplate,
    sync_mode: str
) -> str:
    """解决模板冲突。
    
    Returns:
        "update": 更新本地模板
        "skip": 跳过此模板
        "merge": 合并模板（保留本地自定义字段）
    """
    if sync_mode == "replace":
        return "update"
    elif sync_mode == "update":
        # 只在云端版本更新时才更新
        local_version = local_template.get("version", "0.0")
        if cloud_template.version > local_version:
            return "update"
        return "skip"
    else:  # merge
        # 检查校验和
        local_checksum = calculate_checksum(local_template)
        if local_checksum != cloud_template.checksum:
            return "merge"
        return "skip"


@router.post("", response_model=TemplateSyncResponse)
async def sync_templates(
    request: TemplateSyncRequest,
    background_tasks: BackgroundTasks,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> TemplateSyncResponse:
    """
    从云端同步模板。
    
    Args:
        request: 同步请求参数
    
    Returns:
        同步结果
    """
    try:
        # 检查权限（可选：只允许管理员同步）
        # if not current_user.get("is_admin"):
        #     raise HTTPException(
        #         status_code=status.HTTP_403_FORBIDDEN,
        #         detail="只有管理员可以同步模板"
        #     )
        
        # 获取云端模板
        cloud_templates = await fetch_cloud_templates(
            providers=request.providers,
            categories=request.categories
        )
        
        added = []
        updated = []
        skipped = []
        conflicts = []
        
        for cloud_template in cloud_templates:
            # 检查本地是否存在
            local_template = await db.template_library.find_one({
                "cloud_id": cloud_template.id
            })
            
            if local_template:
                # 解决冲突
                action = await resolve_conflict(
                    local_template,
                    cloud_template,
                    request.sync_mode
                )
                
                if action == "update":
                    # 更新本地模板
                    await db.template_library.update_one(
                        {"cloud_id": cloud_template.id},
                        {
                            "$set": {
                                "name": cloud_template.name,
                                "provider": cloud_template.provider,
                                "category": cloud_template.category,
                                "model_name": cloud_template.model_name,
                                "base_url": cloud_template.base_url,
                                "version": cloud_template.version,
                                "checksum": cloud_template.checksum,
                                "cloud_updated_at": cloud_template.updated_at,
                                "metadata": cloud_template.metadata,
                                "synced_at": datetime.utcnow()
                            }
                        }
                    )
                    updated.append(cloud_template.name)
                    
                elif action == "merge":
                    # 合并模板（保留本地自定义字段）
                    await db.template_library.update_one(
                        {"cloud_id": cloud_template.id},
                        {
                            "$set": {
                                "cloud_version": cloud_template.version,
                                "cloud_checksum": cloud_template.checksum,
                                "cloud_updated_at": cloud_template.updated_at,
                                "cloud_metadata": cloud_template.metadata,
                                "synced_at": datetime.utcnow()
                            }
                        }
                    )
                    updated.append(cloud_template.name)
                    
                    # 记录冲突
                    conflicts.append({
                        "template": cloud_template.name,
                        "action": "merged",
                        "local_version": local_template.get("version"),
                        "cloud_version": cloud_template.version
                    })
                    
                else:  # skip
                    skipped.append(cloud_template.name)
                    
            else:
                # 添加新模板
                template_data = {
                    "id": str(uuid.uuid4()),
                    "cloud_id": cloud_template.id,
                    "name": cloud_template.name,
                    "provider": cloud_template.provider,
                    "category": cloud_template.category,
                    "model_name": cloud_template.model_name,
                    "base_url": cloud_template.base_url,
                    "version": cloud_template.version,
                    "checksum": cloud_template.checksum,
                    "cloud_updated_at": cloud_template.updated_at,
                    "metadata": cloud_template.metadata,
                    "created_at": datetime.utcnow(),
                    "synced_at": datetime.utcnow(),
                    "is_cloud_template": True
                }
                
                await db.template_library.insert_one(template_data)
                added.append(cloud_template.name)
        
        # 更新同步状态
        await db.sync_status.update_one(
            {"user_id": current_user["sub"]},
            {
                "$set": {
                    "last_sync": datetime.utcnow(),
                    "next_sync": datetime.utcnow() + timedelta(hours=24),
                    "last_error": None,
                    "cloud_templates": len(cloud_templates)
                }
            },
            upsert=True
        )
        
        # 记录同步日志
        await db.audit_logs.insert_one({
            "user_id": current_user["sub"],
            "action": "sync_templates",
            "details": {
                "mode": request.sync_mode,
                "added": len(added),
                "updated": len(updated),
                "skipped": len(skipped)
            },
            "timestamp": datetime.utcnow()
        })
        
        return TemplateSyncResponse(
            success=True,
            synced_count=len(added) + len(updated),
            added=added,
            updated=updated,
            skipped=skipped,
            conflicts=conflicts,
            timestamp=datetime.utcnow(),
            next_sync=datetime.utcnow() + timedelta(hours=24)
        )
        
    except Exception as e:
        logger.error(f"模板同步失败: {e}")
        
        # 记录错误
        await db.sync_status.update_one(
            {"user_id": current_user["sub"]},
            {
                "$set": {
                    "last_error": str(e),
                    "last_error_time": datetime.utcnow()
                }
            },
            upsert=True
        )
        
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"模板同步失败: {str(e)}"
        )


@router.get("/status", response_model=TemplateSyncStatus)
async def get_sync_status(
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> TemplateSyncStatus:
    """
    获取同步状态。
    
    Returns:
        同步状态信息
    """
    try:
        # 获取同步状态
        status = await db.sync_status.find_one({"user_id": current_user["sub"]})
        
        # 获取模板统计
        total_templates = await db.template_library.count_documents({})
        local_templates = await db.template_library.count_documents({
            "is_cloud_template": {"$ne": True}
        })
        cloud_templates = await db.template_library.count_documents({
            "is_cloud_template": True
        })
        
        if status:
            return TemplateSyncStatus(
                last_sync=status.get("last_sync"),
                next_sync=status.get("next_sync"),
                auto_sync_enabled=status.get("auto_sync_enabled", False),
                sync_interval_hours=status.get("sync_interval_hours", 24),
                last_error=status.get("last_error"),
                total_templates=total_templates,
                local_templates=local_templates,
                cloud_templates=cloud_templates
            )
        else:
            return TemplateSyncStatus(
                last_sync=None,
                next_sync=None,
                auto_sync_enabled=False,
                sync_interval_hours=24,
                last_error=None,
                total_templates=total_templates,
                local_templates=local_templates,
                cloud_templates=cloud_templates
            )
        
    except Exception as e:
        logger.error(f"获取同步状态失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取同步状态失败"
        )


@router.post("/auto-sync", response_model=Dict[str, Any])
async def configure_auto_sync(
    enabled: bool,
    interval_hours: int = 24,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Dict[str, Any]:
    """
    配置自动同步。
    
    Args:
        enabled: 是否启用自动同步
        interval_hours: 同步间隔（小时）
    
    Returns:
        配置确认
    """
    try:
        # 更新自动同步配置
        await db.sync_status.update_one(
            {"user_id": current_user["sub"]},
            {
                "$set": {
                    "auto_sync_enabled": enabled,
                    "sync_interval_hours": interval_hours,
                    "next_sync": datetime.utcnow() + timedelta(hours=interval_hours) if enabled else None,
                    "updated_at": datetime.utcnow()
                }
            },
            upsert=True
        )
        
        return {
            "success": True,
            "auto_sync_enabled": enabled,
            "sync_interval_hours": interval_hours,
            "next_sync": (datetime.utcnow() + timedelta(hours=interval_hours)).isoformat() if enabled else None
        }
        
    except Exception as e:
        logger.error(f"配置自动同步失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="配置自动同步失败"
        )


@router.post("/offline-mode", response_model=Dict[str, Any])
async def toggle_offline_mode(
    enabled: bool,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> Dict[str, Any]:
    """
    切换离线模式。
    
    Args:
        enabled: 是否启用离线模式
    
    Returns:
        模式状态
    """
    try:
        # 更新离线模式设置
        await db.user_settings.update_one(
            {"user_id": current_user["sub"]},
            {
                "$set": {
                    "offline_mode": enabled,
                    "offline_mode_since": datetime.utcnow() if enabled else None,
                    "updated_at": datetime.utcnow()
                }
            },
            upsert=True
        )
        
        message = "离线模式已启用，将只使用本地模板" if enabled else "在线模式已启用，可以同步云端模板"
        
        return {
            "success": True,
            "offline_mode": enabled,
            "message": message
        }
        
    except Exception as e:
        logger.error(f"切换离线模式失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="切换离线模式失败"
        )


@router.get("/conflicts", response_model=List[Dict[str, Any]])
async def get_sync_conflicts(
    limit: int = 100,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_db)
) -> List[Dict[str, Any]]:
    """
    获取同步冲突列表。
    
    Args:
        limit: 返回的最大数量
    
    Returns:
        冲突列表
    """
    try:
        # 查找有版本差异的模板
        pipeline = [
            {
                "$match": {
                    "is_cloud_template": True,
                    "cloud_version": {"$exists": True},
                    "version": {"$exists": True}
                }
            },
            {
                "$project": {
                    "name": 1,
                    "provider": 1,
                    "local_version": "$version",
                    "cloud_version": 1,
                    "checksum": 1,
                    "cloud_checksum": 1,
                    "synced_at": 1,
                    "has_conflict": {
                        "$ne": ["$checksum", "$cloud_checksum"]
                    }
                }
            },
            {
                "$match": {"has_conflict": True}
            },
            {"$limit": limit}
        ]
        
        conflicts = await db.template_library.aggregate(pipeline).to_list(None)
        
        # 格式化输出
        for conflict in conflicts:
            conflict["_id"] = str(conflict["_id"])
            if conflict.get("synced_at"):
                conflict["synced_at"] = conflict["synced_at"].isoformat()
        
        return conflicts
        
    except Exception as e:
        logger.error(f"获取同步冲突失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取同步冲突失败"
        )